home *** CD-ROM | disk | FTP | other *** search
- // June 15, 1994 - KF5MG - Jack Snodgrass
- //
- // This code was adapted/copied from the SAM.C code. The code to process
- // the QRZ disk was taken from the QRZ CD-ROM. This code could work
- // with the name and zipcode versions of the Callbook data, but as-is, it
- // only processes callsigns.
- //
- #include <ctype.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <io.h>
- #include <fcntl.h>
-
- #define reclen 160
- #include "global.h"
- #ifdef QRZCALLB
- #include "mbuf.h"
- #include "socket.h"
- #include "session.h"
- #include "proc.h"
- #include "netuser.h"
- #include "commands.h"
- #include "tty.h"
- #include "config.h"
-
- extern char *Callserver; /* buckbook.c */
- int cb_lookup __ARGS((int s,char *,FILE *));
-
- /* does the actual lookup. */
- int qrzfind(char *,int s, FILE *);
- /* Parse QRZ data record. */
- void parse_record(char *, int s);
- /* Format QRZ Database Date. */
- void formatdate(char *);
-
- /* Gobal variables. */
- char pretty_date[12];
- char prettycall[7];
- char *qrzdir;
- char *qrzdrv;
-
- /* Taken from the QRZ CD-ROM disk.
- * This block is located at the start of each index
- */
- /*
- * New Index Header Block Definition
- */
- typedef struct {
- char dataname[16]; /* Name of the data file */
- char bytesperkey[8]; /* Data Bytes per Index Item */
- char numkeys[8]; /* Number of items in this index */
- char keylen[8]; /* Length of each key item in bytes */
- char version[8]; /* Database Version ID */
- } index_header;
-
- /*
- * Old Index Header Block Definition
- */
- typedef struct {
- char dataname[13]; /* Name of the data file */
- long bytesperkey; /* Data Bytes per Index Item */
- int numkeys; /* Number of items in this index */
- int keylen; /* Length of each key item in bytes */
- } old_index_header ;
-
- /* return values - 2= Callbook Error 1= not found, 0= okay */
- int cb_lookup(s, str, fp)
- int s;
- char *str;
- FILE *fp;
- {
- if(qrzfind(str,s,fp))
- return 0;
- else
- return 1;
- }
-
- int qrzfind(char *call_in, int s, FILE *fpout)
- {
- index_header idxhdr;
- old_index_header oldidxhdr;
-
- FILE *fp;
- char *buf;
- char *bufptr;
- char IndexFile[] = "callbkc.idx";
- int size;
- int bytesperkey; /* Data Bytes per Index Item */
- int numkeys; /* Number of items in this index */
- int keylen; /* Length of each key item in bytes */
- int slots;
- int i,j,k,found,slotcnt;
- long fpos;
- long frc;
- char temp[255];
- char *cp;
- char *cp2;
- char call[8];
-
-
- /* call needs to be blank filled. */
- strcpy(call," ");
-
- /* Pretty call holds the original, un-qrz-formatted callsign. */
- strcpy(prettycall, call_in);
- strupr(prettycall);
-
-
- k = strlen(call_in);
- if (k>6) {
- usprintf(s,"Callsign too long.\n");
- return 0;
- }
-
- /* Callsigns in the QRZ Index are stored in a weird format. They are */
- /* 6 characters in length ( padded with spaces ), in the format of */
- /* ccdccc where the digit is always in the 3rd posistion. If the */
- /* callsign is a 1-by-something callsign, the 2nd posistion will be */
- /* blank. KF5MG will be stored as KF5MGb. N5VGC will be stored as */
- /* Nb5VGC. ( the b are spaces ) */
- /* */
- i = 1;
- j = 1;
- call[0] = call_in[0];
- if(!isdigit(call_in[j]))
- call[i++] = call_in[j++];
- else
- call[i++] = ' ';
- if(isdigit(call_in[j])) {
- call[i++] = call_in[j++];
- } else {
- /* No digit found in posistion 2 or 3. */
- usprintf(s,"Error parsing callsign... %s\n", call_in);
- return 0;
- }
- if(isalpha(call_in[j]))
- call[i++] = call_in[j];
- else
- call[i++] = ' ';
- j++;
- if(isalpha(call_in[j]))
- call[i++] = call_in[j];
- else
- call[i++] = ' ';
- j++;
- if(isalpha(call_in[j]))
- call[i++] = call_in[j];
- else
- call[i++] = ' ';
-
-
- call[6] = 0;
- strupr(call);
-
-
- qrzdir = strdup(getenv("QRZPATH"));
- qrzdrv = strdup(getenv("QRZDRV"));
-
- if(qrzdir == NULLCHAR)
- qrzdir = strdup("\\callbk");
-
- if(qrzdrv == NULLCHAR)
- qrzdrv = strdup("C:");
-
- /* Open the index file. We'll use it to tell us the name of the */
- /* database file. We'll also find the database version and some */
- /* other useful info. */
- /* */
- sprintf(temp,"%s%s\\%s",qrzdrv,qrzdir,IndexFile);
- if((fp = fopen(temp,"rt"))==NULL) {
- usprintf(s,"Error opening Index: %s\n",temp);
- free(qrzdir);
- free(qrzdrv);
- return 0;
- }
-
- size = fread(&idxhdr,sizeof(idxhdr),1,fp);
- if(size != 1) {
- usprintf(s,"Error reading Index Header.\n");
- free(qrzdir);
- free(qrzdrv);
- return 0;
- }
-
- // Old Style Index has a '0' at pos 16 and 17.
- if((int)idxhdr.dataname[16] != 0) {
- // This is a 'new' style index
- bytesperkey = atoi(idxhdr.bytesperkey); /* size of data area. */
- numkeys = atoi(idxhdr.numkeys); /* # of keys in file. */
- keylen = atoi(idxhdr.keylen); /* length of each key. */
- } else {
- // This is an 'old' style index.
- // rewind the file and read the header using the old_index_header struct.
- rewind(fp);
-
- size = fread(&oldidxhdr,sizeof(oldidxhdr),1,fp);
- if(size != 1) {
- usprintf(s,"Error reading Index Header.\n");
- free(qrzdir);
- free(qrzdrv);
- return 0;
- }
- bytesperkey = oldidxhdr.bytesperkey; /* size of data area. */
- numkeys = oldidxhdr.numkeys; /* # of keys in file. */
- keylen = oldidxhdr.keylen; /* length of each key. */
- }
-
- /* This is a 10K ish buffer. Each 'key' in the index covers almost */
- /* 10K of data. Once you find the correct key, you have to read the */
- /* 10K chunk of data from the data file. You then start searching */
- /* for the correct callsign. This code uses the same 10k buffer to */
- /* scan the index file ( typically 40K so you might do 4 reads ) to */
- /* save memory. Once you've found the correct key, you calculate the */
- /* offset into the database. You then read the data base into your */
- /* 10K buffer.
- /* */
- bufptr = malloc(bytesperkey+400); /* Get space for buffer */
- slots = bytesperkey / keylen; /* Calculate # of slots */
- found = 0;
- slotcnt = 0;
-
- do {
- /* Point floating buf pointer to start of big buffer. */
- buf = bufptr;
- /* Read slots number of entries that are keylen in size */
- size = fread(buf,keylen,slots,fp);
- if(size == 0) {
- usprintf(s,"Error reading Index file.\n");
- found = 2;
- }
-
- /* Start scanning Index buffer. If the data is less than your search */
- /* Value... keep going. If the Data is greater, then your done. You */
- /* then subtract one from your slotcnt (unless it's an exact match) */
- /* and that's the closet record to your data. */
- /* */
- for(i=0;i<size;i++) {
- slotcnt++;
- strncpy(temp,(char *)buf,keylen);
- temp[keylen] = 0;
- if(strncmp(&temp[3],&call[3],3) >= 0) {
- if(strncmp(&temp[3],&call[3],3) > 0) {
- found = 1;
- slotcnt--;
- }
- else
- if(strncmp(&temp[2],&call[2],4) > 0) {
- slotcnt--;
- found = 1;
- }
- }
- if(found)
- break;
- /*
- *buf++;
- *buf++;
- *buf++;
- *buf++;
- *buf++;
- *buf++;
- */
- buf += 6;
- }
- } while(!found); /* enddo */
-
- slotcnt--;
-
- /* We're done with the Index so we can close it. */
- fclose(fp);
-
- /* If we found a match, the calculate the offset and read the data. */
- if(found == 1) {
- buf = bufptr;
- sprintf(temp,"%s%s\\%s",qrzdrv,qrzdir,idxhdr.dataname);
- if((fp = fopen(temp,"rt"))==NULL) {
- usprintf(s,"Error opening Database: %s\n",temp);
- free(bufptr);
- free(qrzdir);
- free(qrzdrv);
- return 0;
- }
-
- /* Just to to be save, we read 200 bytes before and after so we */
- /* don't miss anything. */
- /* seek to correct posistion in file . */
- fpos = (long) bytesperkey*slotcnt;
- fpos -= 200;
-
- frc = lseek(fileno(fp),(long) fpos,SEEK_SET);
- if(frc < 1) {
- usprintf(s,"Error seeking Database file.\n");
- free(bufptr);
- free(qrzdir);
- free(qrzdrv);
- return 0;
- }
-
- /* Read slot from callbk file. */
- size = fread(buf,bytesperkey+400,1,fp);
- if(size < 1) {
- usprintf(s,"Error reading Database file.\n");
- free(bufptr);
- free(qrzdir);
- free(qrzdrv);
- return 0;
- }
-
- /* Done with data file. Now we can close it too. Our users is either */
- /* in our buffer or doesn't exist. */
- fclose(fp);
-
- i = 0;
- for(;;) {
- if(i>bytesperkey+400)
- break;
- k = strcspn(buf,"\n");
- strncpy(temp,buf,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- /*
- *buf++;
- */
- buf += 1;
-
- /* Find our user. */
- if(strncmp(temp,call,6) == 0) {
- /* Found it. Now read and format the data. */
- parse_record(temp,s);
- break;
- }
- i+=k;
- }
- }
- /* Done with the buffer. */
- free(bufptr);
- free(qrzdir);
- free(qrzdrv);
- return found;
- }
-
- void parse_record(char *record, int s) {
- /*
- * Standard Record Format
- */
- char callsign[7]; /* Call Sign Decoded */
- char lastname[33]; /* Last Name */
- char namesuffix[3]; /* Name Suffix */
- char frstname[33]; /* First Name */
- char middleinit[3]; /* Middle Initial */
- char datelicensed[6]; /* Date Licensed mm/dd/yy */
- char dateborn[6]; /* Date Born */
- char dateexpires[6]; /* Date Born */
- char streetaddr[33]; /* Street Address */
- char city[33]; /* City */
- char state[3]; /* State Code */
- char zipcode[6]; /* Zip Code */
- char license_class[3]; /* License Class */
- char prevcall[7]; /* Previous Call */
- char prevclass[3]; /* Previous Class */
-
- char *cp;
- char fullname[80];
- char address[80];
- char temp[255];
- char temp2[255];
- int i,j,k;
-
- strcpy(temp2,record);
- cp = temp2;
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(callsign,temp);
-
- if(strlen(record) < 16) {
- usprintf(s,"%s is an old call for %s\n", prettycall, cp);
- return;
- }
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(lastname,temp);
-
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(namesuffix,temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(frstname,temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(middleinit,temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(dateborn,temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(datelicensed, temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(dateexpires,temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(streetaddr,temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(city,temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(state,temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(zipcode,temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(license_class,temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(prevcall,temp);
-
- k = strcspn(cp,",");
- strncpy(temp,cp,k);
- temp[k] = 0;
- for(j=0;j<=k;j++)
- cp += 1;
- strcpy(prevclass,temp);
-
- sprintf(fullname,"%s %s. %s, %s",frstname, middleinit, lastname, namesuffix);
- sprintf(address, "%s, %s, %s", city, state, zipcode);
-
- usprintf(s,"\n%-8s", prettycall);
- usprintf(s,"%-45s", fullname);
- formatdate(dateborn);
- usprintf(s,"Born: %s\n", pretty_date);
-
- usprintf(s,"%-8s%-45s","", streetaddr);
- formatdate(datelicensed);
- usprintf(s,"Class: %s %s\n", license_class, pretty_date);
-
- usprintf(s,"%-8s%-45s", "", address);
- usprintf(s,"Prev: %s %s\n", prevclass, prevcall);
-
- formatdate(dateexpires);
- usprintf(s,"%52s Expir: %s\n", "", pretty_date);
-
- return;
- }
-
- void formatdate(char *date){
- char year[5];
- char rest[4];
- int mon;
- int day;
- int days;
- int years;
- int i;
-
- int dayarray[12] = { 31, 60, 91, 121, 152, 182,
- 213, 244, 274, 305, 335, 366 };
-
- strncpy(year,date,2);
- year[2] = 0;
- years = atoi(year);
- if(years < 20)
- years += 2000;
- else
- years += 1900;
-
- strncpy(rest,&date[2],3);
- rest[3] = 0;
- days = atoi(rest);
-
- if((years % 4) != 0)
- if(days > 59)
- days++;
-
- for(i=0;i<12;i++){
- if(days <= dayarray[i]) {
- mon = i;
- day = days - dayarray[i-1];
- break;
- }
- }
- sprintf(pretty_date, "%02d/%02d/%04d", mon+1,day,years);
- }
- #endif